"""
Relaxation Methods

Implements under-relaxation schemes for iterative solution of nonlinear systems.
"""

"""
    under_relax!(field_new::Array{Float64}, field_old::Array{Float64}, α::Float64)

Apply under-relaxation: field_new = field_old + α*(field_new - field_old)

# Arguments
- `field_new::Array{Float64}`: New field values (modified in-place)
- `field_old::Array{Float64}`: Previous field values
- `α::Float64`: Relaxation factor (0 < α ≤ 1)
"""
function under_relax!(field_new::Array{Float64}, field_old::Array{Float64}, α::Float64)
    @assert 0 < α ≤ 1 "Relaxation factor must be in (0,1]"
    
    @inbounds for i in eachindex(field_new)
        if !isnan(field_old[i]) && !isnan(field_new[i])
            field_new[i] = field_old[i] + α * (field_new[i] - field_old[i])
        end
    end
end

"""
    auto_adjust_relaxation_parameters(α_ψ::Union{Float64,Nothing}, α_ω::Union{Float64,Nothing}, 
                                     n::Int, solver::Symbol, verbose::Bool) -> (Float64, Float64)

Automatically adjust relaxation parameters based on problem size and solver type.
"""
function auto_adjust_relaxation_parameters(α_ψ::Union{Float64,Nothing}, α_ω::Union{Float64,Nothing}, 
                                          n::Int, solver::Symbol, verbose::Bool)
    
    # Use provided values if both are specified
    if α_ψ !== nothing && α_ω !== nothing
        if verbose
            println("[Relaxation] Using specified parameters: α_ψ=$α_ψ, α_ω=$α_ω")
        end
        return α_ψ, α_ω
    end
    
    # Auto-adjust based on grid size and solver
    if solver == :julia || solver == :gcr
        # Pure Julia/GCR solvers - generally more stable
        if n <= 32
            α_ψ_auto = 0.6
            α_ω_auto = 0.8
        elseif n <= 64
            α_ψ_auto = 0.5
            α_ω_auto = 0.7
        else
            α_ψ_auto = 0.4
            α_ω_auto = 0.6
        end
        
    elseif solver == :petsc
        # PETSc solver - may need more conservative relaxation
        if n <= 32
            α_ψ_auto = 0.4
            α_ω_auto = 0.6
        elseif n <= 64
            α_ψ_auto = 0.2
            α_ω_auto = 0.4
        else
            α_ψ_auto = 0.1
            α_ω_auto = 0.2
            if verbose
                @warn "Large grid size with PETSc may require very slow relaxation"
            end
        end
        
    else # fallback/unknown solver
        α_ψ_auto = 0.3
        α_ω_auto = 0.5
    end
    
    # Use provided values where available, auto values otherwise
    α_ψ_final = α_ψ !== nothing ? α_ψ : α_ψ_auto
    α_ω_final = α_ω !== nothing ? α_ω : α_ω_auto
    
    if verbose
        status_ψ = α_ψ !== nothing ? "specified" : "auto"
        status_ω = α_ω !== nothing ? "specified" : "auto"
        println("[Relaxation] Parameters: α_ψ=$α_ψ_final ($status_ψ), α_ω=$α_ω_final ($status_ω)")
    end
    
    return α_ψ_final, α_ω_final
end